import socket from '@ohos.net.socket';
import wifiManager from '@ohos.wifiManager';

export interface MessageCallback {
  (message: string): void;
}

export class UdpClientHelper {
  udp: socket.UDPSocket;

  connectUdpServer(messageCallback: MessageCallback) {
    this.udp = socket.constructUDPSocketInstance();

    // 订阅TCPSocket相关的订阅事件
    this.udp.on('message', value => {
      console.log("on message");
      let buffer = value.message;
      let dataView = new DataView(buffer);
      let str = "";
      for (let i = 0; i < dataView.byteLength; ++i) {
        str += String.fromCharCode(dataView.getUint8(i));
      }
      console.log("on connect received:" + str);
      messageCallback(str);
    });

    this.udp.on('close', () => {
      console.log("on close");
    });

    // 获取本机 IP
    let localAddress = resolveIP(wifiManager.getIpInfo().ipAddress);
    // 绑定本机 IP
    this.udp.bind({ address: localAddress }, err => {
      if (err) {
        console.log('connect fail');
        return;
      }
      console.log('connect success');
    });
  }

  async sendMessage(message: string, hostIp, hostPort): Promise<boolean> {
    if (this.udp !== undefined) {
      try {
        await this.udp.send({
          data: message,
          address: {
            address: hostIp,
            port: hostPort
          }
        });
        return true;
      } catch (err) {
        if (err) {
          console.error('Error: ' + JSON.stringify(err));
          return false;
        }
      }
    } else {
      return false;
    }
  }

  stop() {
    if (this.udp !== undefined) {
      this.udp.close((err) => {
        if (err) {
          console.log('close socket failed. ' + JSON.stringify(err));
        }
        console.log('close socket.')
      });
      this.udp.off('message');
      this.udp.off('close');
    }
  }
}

function resolveIP(ip: number): string {
  if (ip < 0 || ip > 0xFFFFFFFF) {
    throw ('The number is not normal!');
  }
  return (ip >>> 24) + '.' + (ip >> 16 & 0xFF) + '.' + (ip >> 8 & 0xFF) + '.' + (ip & 0xFF);
}